package com.meetingshow.meeting.uiservice;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.validation.groups.Default;

import org.apache.log4j.Logger;

import com.meetingshow.common.base.service.model.QueryResults;
import com.meetingshow.common.base.uiservice.BaseUIServiceImp;
import com.meetingshow.common.base.uiservice.exception.BaseUIServiceException;
import com.meetingshow.common.validator.RemoveValidator;
import com.meetingshow.common.validator.UpdateValidator;
import com.meetingshow.meeting.dao.model.MeetingPO;
import com.meetingshow.meeting.dao.model.UserFollowPO;
import com.meetingshow.meeting.service.IMeetingService;
import com.meetingshow.meeting.service.IUserFollowService;
import com.meetingshow.meeting.service.model.MeetingQueryParas;
import com.meetingshow.meeting.service.model.UserFollowQueryParas;
import com.meetingshow.meeting.uiservice.model.MeetingQueryParasVO;
import com.meetingshow.meeting.uiservice.model.MeetingVO;
import com.meetingshow.privilege.dao.model.UserPO;
import com.meetingshow.utils.BaseUtil;

public class UIMeetingServiceImp extends BaseUIServiceImp implements IUIMeetingService {
    
    public final static Logger logger = Logger.getLogger(UIMeetingServiceImp.class);

    private IMeetingService meetingService;
    private IUserFollowService userFollowService;
    
    /**
     * @return the meetingService
     */
    public IMeetingService getMeetingService() {
        return meetingService;
    }

    /**
     * @param meetingService the meetingService to set
     */
    public void setMeetingService(IMeetingService meetingService) {
        this.meetingService = meetingService;
    }
    
    /**
     * @return the userFollowService
     */
    public IUserFollowService getUserFollowService() {
        return userFollowService;
    }

    /**
     * @param userFollowService the userFollowService to set
     */
    public void setUserFollowService(IUserFollowService userFollowService) {
        this.userFollowService = userFollowService;
    }

    @Override
    public Integer saveMeeting(MeetingVO meetingVO)
            throws BaseUIServiceException {
        
        if (!BaseUtil.objectNotNull(meetingVO)) {
            this.throwValidaterException("meetingVO is null.");
        }
        
        meetingVO.setCreateTime(new Date());
        meetingVO.setFollowCount(0);

        validateThrowEx(meetingVO);
        
        try {
            Integer meetingId = getMeetingService().saveMeeting(meetingVO.toMeetingPO());
            meetingVO.setMeetingId(meetingId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        return meetingVO.getMeetingId();
    }

    @Override
    public void updateMeeting(MeetingVO meetingVO)
            throws BaseUIServiceException {
        if (!BaseUtil.objectNotNull(meetingVO)) {
            this.throwValidaterException("meetingVO is null.");
        }
        
        validateThrowEx(meetingVO, Default.class, UpdateValidator.class);
        
        MeetingQueryParas meetingQueryParas = new MeetingQueryParas();
        meetingQueryParas.setMeetingId_e(String.valueOf(meetingVO.getMeetingId()));
        
        QueryResults<MeetingPO> meetingQueryResults = null;
        try {
            meetingQueryResults = getMeetingService().queryMeeting(meetingQueryParas);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        if (QueryResults.resultsListNotNull(meetingQueryResults)) {
            MeetingPO persistMeetingPO = meetingQueryResults.getResultList().get(0);
            persistMeetingPO.setAbstracT(meetingVO.getAbstracT());
            persistMeetingPO.setCharge(meetingVO.getCharge());
            persistMeetingPO.setCity(meetingVO.getCity().toCityPO());
            persistMeetingPO.setContactor(meetingVO.getContactor());
            persistMeetingPO.setContactFax(meetingVO.getContactFax());
            persistMeetingPO.setContactPhone(meetingVO.getContactPhone());
            persistMeetingPO.setCoOrganizer(meetingVO.getCoOrganizer());
            persistMeetingPO.setEmail(meetingVO.getEmail());
            persistMeetingPO.setEndDate(meetingVO.getEndDate());
            persistMeetingPO.setHot(meetingVO.getHot());
            persistMeetingPO.setImage(meetingVO.getImage());
            persistMeetingPO.setIndustry(meetingVO.getIndustry().toIndustryPO());
            persistMeetingPO.setLocation(meetingVO.getLocation());
            persistMeetingPO.setMeetingType(meetingVO.getMeetingType().toMeetingTypePO());
            persistMeetingPO.setName(meetingVO.getName());
            persistMeetingPO.setNameEn(meetingVO.getNameEn());
            persistMeetingPO.setOrganizer(meetingVO.getOrganizer());
            persistMeetingPO.setRecommend(meetingVO.getRecommend());
            persistMeetingPO.setSponsor(meetingVO.getSponsor());
            persistMeetingPO.setValuable(meetingVO.getValuable());
            persistMeetingPO.setStartDate(meetingVO.getStartDate());
            persistMeetingPO.setWebsite(meetingVO.getWebsite());
            persistMeetingPO.setWeiboName(meetingVO.getWeiboName());
            persistMeetingPO.setWeiboUrl(meetingVO.getWeiboUrl());
            
            try {
                getMeetingService().updateMeeting(persistMeetingPO);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                throw new BaseUIServiceException(e);
            }
        }
    }

    @Override
    public void removeMeeting(MeetingVO meetingVO)
            throws BaseUIServiceException {
        if (!BaseUtil.objectNotNull(meetingVO)) {
            this.throwValidaterException("meetingVO is null.");
        }
        
        validateThrowEx(meetingVO, RemoveValidator.class);
        
        MeetingQueryParas meetingQueryParas = new MeetingQueryParas();
        meetingQueryParas.setMeetingId_e(String.valueOf(meetingVO.getMeetingId()));
        
        QueryResults<MeetingPO> meetingQueryResults = null;
        try {
            meetingQueryResults = getMeetingService().queryMeeting(meetingQueryParas);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        if (QueryResults.resultsListNotNull(meetingQueryResults)) {
            MeetingPO persistMeetingPO = meetingQueryResults.getResultList().get(0);
            try {
                getMeetingService().removeMeeting(persistMeetingPO);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                throw new BaseUIServiceException(e);
            }
        }
    }

    @Override
    public MeetingVO loadMeetingById(Integer meetingId)
            throws BaseUIServiceException {
        if (meetingId == null)
            this.throwValidaterException("meetingId is null.");
        
        MeetingPO meetingPO = null;
        try {
            meetingPO = getMeetingService().loadMeetingById(meetingId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        if (meetingPO == null)
            return null;
        else
            return new MeetingVO(meetingPO);
    }
    
    @Override
    public QueryResults<MeetingVO> queryMeeting(
            MeetingQueryParasVO meetingQueryParasVO)
            throws BaseUIServiceException {
        if (!BaseUtil.objectNotNull(meetingQueryParasVO)) {
            this.throwValidaterException("meetingQueryParasVO is null.");
        }
        
        validateThrowEx(meetingQueryParasVO);
        
        QueryResults<MeetingPO> meetingPOQueryResults = null;
        try {
            meetingPOQueryResults = getMeetingService().queryMeeting(meetingQueryParasVO.toMeetingQueryParas());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        QueryResults<MeetingVO> meetingVOQueryResults = new QueryResults<MeetingVO>();
        List<MeetingVO> meetingVOList = new ArrayList<MeetingVO>();
        if (QueryResults.resultsListNotNull(meetingPOQueryResults)) {
            for (MeetingPO meetingPO : meetingPOQueryResults.getResultList()) {
                if (BaseUtil.objectNotNull(meetingPO)) {
                    meetingVOList.add(new MeetingVO(meetingPO));
                }
            }
        }
        
        meetingVOQueryResults.setFirstResultNo(meetingPOQueryResults.getFirstResultNo());
        meetingVOQueryResults.setResultsPerGroup(meetingPOQueryResults.getResultsPerGroup());
        meetingVOQueryResults.setResultList(meetingVOList);
        meetingVOQueryResults.setTotalResultsNum(meetingPOQueryResults.getTotalResultsNum());
        
        return meetingVOQueryResults;
    }

    @Override
    public int addFollowCount(Integer meetingId, Integer userId) throws BaseUIServiceException {
        if (meetingId == null)
            this.throwValidaterException("meetingId is null.");
        
        UserFollowQueryParas userFollowQueryParas = new UserFollowQueryParas();
        userFollowQueryParas.setMeetingId_e(String.valueOf(meetingId));
        userFollowQueryParas.setUserId_e(String.valueOf(userId));
        QueryResults<UserFollowPO> queryResults = null;
        try {
            queryResults = getUserFollowService().queryUserFollow(userFollowQueryParas);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        if (QueryResults.resultsListNotNull(queryResults)) {
            throw new BaseUIServiceException("The user have already followed the meeting.");
        }
        
        UserFollowPO userFollowPO = new UserFollowPO();
        
        MeetingPO meetingPO = new MeetingPO();
        meetingPO.setMeetingId(meetingId);
        
        UserPO userPO = new UserPO();
        userPO.setUserId(userId);
        
        userFollowPO.setMeeting(meetingPO);
        userFollowPO.setUser(userPO);
        userFollowPO.setCreateTime(new Date());
        
        int count = 0;
        try {
            count = getMeetingService().addFollowCount(userFollowPO);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        return count;
    }
    
    @Override
    public int subFollowCount(Integer meetingId, Integer userId) throws BaseUIServiceException {
        if (meetingId == null)
            this.throwValidaterException("meetingId is null.");
        
        UserFollowQueryParas userFollowQueryParas = new UserFollowQueryParas();
        userFollowQueryParas.setMeetingId_e(String.valueOf(meetingId));
        userFollowQueryParas.setUserId_e(String.valueOf(userId));
        QueryResults<UserFollowPO> queryResults = null;
        try {
            queryResults = getUserFollowService().queryUserFollow(userFollowQueryParas);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        if (!QueryResults.resultsListNotNull(queryResults)) {
            throw new BaseUIServiceException("The user didn't follow the meeting.");
        }
        UserFollowPO userFollowPO = queryResults.getResultList().get(0);
        
        int count = 0;
        try {
            count = getMeetingService().subFollowCount(userFollowPO);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        return count;
    }
}
